﻿/*
 * ring_buffer.c
 *
 *  Created on: 2019年9月23日
 *      Author: 508
 */
#include "ring_buffer.h"

std::mutex memLock;

int ring_buffer_init(ring_buffer *p, char*mem, uint32_t size)
{
	//assert(buffer);
	//struct ring_buffer *ring_buf = NULL;
	if (!is_power_of_2(size))
	{
		printf("size must be power of 2.\n");
		return -1;
	}
	memset(p, 0, sizeof(struct _ring_buffer));
	p->buffer = mem;
	p->size = size;
	p->in = 0;
	p->out = 0;
	//   ring_buf->f_lock = f_lock;
	return 0;
}
//释放缓冲区
void ring_buffer_reset(ring_buffer *ring_buf)
{
	if (ring_buf)
	{
		if (ring_buf->buffer)
		{
			memset(ring_buf->buffer, 0, ring_buf->size);
			ring_buf->in = 0;
			ring_buf->out = 0;
		}
	}
}

//缓冲区的长度
uint32_t __ring_buffer_len(ring_buffer *ring_buf)
{
	return (ring_buf->in - ring_buf->out);
}

//从缓冲区中取数据
uint32_t __ring_buffer_get(ring_buffer *ring_buf, uint8_t * buffer, uint32_t size)
{
	if (!ring_buf || !buffer)
		return 0;
	uint32_t len = 0;
	size = Min(size, ring_buf->in - ring_buf->out);
	/* first get the data from fifo->out until the end of the buffer */
	len = Min(size, ring_buf->size - (ring_buf->out & (ring_buf->size - 1)));
	memcpy(buffer, ring_buf->buffer + (ring_buf->out & (ring_buf->size - 1)), len);
	/* then get the rest (if any) from the beginning of the buffer */
	memcpy(buffer + len, ring_buf->buffer, size - len);
	ring_buf->out += size;
	return size;
}
//向缓冲区中存放数据
uint32_t __ring_buffer_put(ring_buffer *ring_buf, uint8_t *buffer, uint32_t size)
{
	if (!ring_buf || !buffer)
		return 0;
	uint32_t len = 0;
	size = Min(size, ring_buf->size - ring_buf->in + ring_buf->out);
	/* first put the data starting from fifo->in to buffer end */
	len = Min(size, ring_buf->size - (ring_buf->in & (ring_buf->size - 1)));
	memcpy(ring_buf->buffer + (ring_buf->in & (ring_buf->size - 1)), buffer, len);
	/* then put the rest (if any) at the beginning of the buffer */
	memcpy(ring_buf->buffer, buffer + len, size - len);
	ring_buf->in += size;
	return size;
}

uint32_t ring_buffer_len(ring_buffer *ring_buf)
{
	uint32_t len = 0;
	memLock.lock();
	len = __ring_buffer_len(ring_buf);
	memLock.unlock();
	return len;
}

uint32_t ring_buffer_get(ring_buffer *ring_buf, uint8_t *buffer, uint32_t size)
{
	uint32_t ret;
	memLock.lock();
	ret = __ring_buffer_get(ring_buf, buffer, size);
	//buffer中没有数据
	if (ring_buf->in == ring_buf->out)
		ring_buf->in = ring_buf->out = 0;
	memLock.unlock();
	return ret;
}

uint32_t ring_buffer_put(ring_buffer *ring_buf, uint8_t *buffer, uint32_t size)
{
	uint32_t ret;
	memLock.lock();
	ret = __ring_buffer_put(ring_buf, buffer, size);
	memLock.unlock();
	return ret;
}


